package admin_article_api

import (
	"blog_go/global"
	"blog_go/models"
	"blog_go/models/ctype"
	"blog_go/models/res"
	"blog_go/utils"
	md "github.com/JohannesKaufmann/html-to-markdown"
	"github.com/PuerkitoBio/goquery"
	"github.com/gin-gonic/gin"
	"github.com/russross/blackfriday"
	"github.com/sirupsen/logrus"
	"gorm.io/gorm"
	"strings"
)

type ArticleUpdateReq struct {
	ID       uint64      `json:"id"  binding:"required"`
	Title    string      `json:"title" binding:"required" msg:"标题不能为空"`      // 文章标题
	Abstract string      `json:"abstract"`                                   // 文章简介
	Content  string      `json:"content" binding:"required" msg:"内容不能为空"`    // 文章内容
	Category string      `gorm:"size:20" json:"category"`                    // 文章分类
	Source   string      `json:"source"`                                     // 文章来源
	Link     string      `json:"link"`                                       // 原文链接
	ImageID  uint        `json:"image_id" binding:"required" msg:"文章封面不能为空"` // 文章封面id
	Tags     ctype.Array `json:"tags"`                                       // 文章标签
}

// ArticleUpdate 文章更新
// @Tags 文章管理
// @Summary 文章更新
// @Description 文章更新
// @Param params body ArticleUpdateReq true "入参json"
// @Param token header string true "token"
// @Router /api/admin/article/update [put]
// @Produce json
// @Success 200 {object} res.Response{data=bool}
func (AdminArticleApi) ArticleUpdate(c *gin.Context) {
	var req ArticleUpdateReq
	if err := c.ShouldBindJSON(&req); err != nil {
		logrus.Error(err)
		panic(err)
	}
	_claims := c.MustGet(utils.Claims)
	claims := _claims.(*utils.CustomClaims)
	// 处理content
	basic := blackfriday.MarkdownBasic([]byte(req.Content))
	// 是不是有script标签
	doc, _ := goquery.NewDocumentFromReader(strings.NewReader(string(basic)))
	nodes := doc.Find("script").Nodes
	if len(nodes) > 0 {
		// 有script标签
		doc.Find("script").Remove()
		converter := md.NewConverter("", true, nil)
		html, _ := doc.Html()
		markdown, _ := converter.ConvertString(html)
		req.Content = markdown
	}
	if req.Abstract == "" {
		// 只截取文本不截取html
		abs := []rune(doc.Text())
		if len(abs) > 100 {
			req.Abstract = string(abs[:100])
		} else {
			req.Abstract = string(abs)
		}
	}
	var imageModel models.ImageModel
	err := global.DB.Take(&imageModel, req.ImageID).Error
	if err != nil {
		logrus.Error(err)
		panic(err)
	}
	// 查询tag
	var tagModelList []models.TagModel
	affected := global.DB.Where("title in ?", req.Tags).Find(&tagModelList).RowsAffected
	if affected != int64(len(req.Tags)) {
		panic("有一个tag不存在")
	}
	// 查询文章
	var article models.ArticleModel
	err = global.DB.Find(&article, req.ID).Error
	if err != nil {
		logrus.Error(err)
		panic(err)
	}
	if article.Title != req.Title {
		var count int64
		global.DB.Model(&article).Where("title = ?", req.Title).Count(&count)
		if count > 0 {
			panic("标题重复了")
		}
	}
	err = global.DB.Transaction(func(tx *gorm.DB) error {
		// 删除关系tag关系表
		if err := tx.Model(&article).Association("TagModels").Clear(); err != nil {
			return err
		}
		// 修改文章
		article := &models.ArticleModel{
			Title:     req.Title,
			Abstract:  req.Abstract,
			Content:   req.Content,
			Category:  req.Category,
			Source:    req.Source,
			Link:      req.Link,
			ImageID:   req.ImageID,
			Tags:      req.Tags,
			UserID:    claims.UserID,
			NickName:  claims.NickName,
			ImagePath: imageModel.Path,
		}
		err := tx.Create(&article).Error
		if err != nil {
			return err
		}
		// 添加tag关系表
		if len(tagModelList) > 0 {
			var article2TagModelList []models.Article2TagModel
			for _, tag := range tagModelList {
				article2TagModelList = append(article2TagModelList, models.Article2TagModel{
					ArticleID: article.ID,
					TagID:     tag.ID,
				})
			}
			err := tx.Create(article2TagModelList).Error
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		logrus.Error(err)
		panic(err)
	}
	res.Ok("添加文章成功", true, c)
}
